From 0600d3d7e4c85eefa479d9735df37af707a31438 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 3 May 2013 10:42:40 +0200 Subject: [PATCH] GtkWidget: Use gdk_window_get_children_for_user_data This makes iterating over the children a lot faster, as we're not doing lots of intra-library calls and type checks. We're still in some sence O(n^2) since we iterate over each child window for each widget, but the profiles look much better. --- gtk/gtkwidget.c | 55 ++++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 19e026a401..2139d7badc 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -6402,7 +6402,7 @@ _gtk_widget_draw_windows (GdkWindow *window, cairo_pattern_t *pattern; gboolean do_clip; GtkWidget *widget = NULL; - GList *l; + GList *children, *l; int x, y; if (!gdk_window_is_viewable (window)) @@ -6438,29 +6438,26 @@ _gtk_widget_draw_windows (GdkWindow *window, _gtk_widget_draw_internal (widget, cr, do_clip, window); cairo_restore (cr); - for (l = g_list_last (gdk_window_peek_children (window)); - l != NULL; - l = l->prev) + children = gdk_window_get_children_with_user_data (window, widget); + for (l = children; l != NULL; l = l->next) { GdkWindow *child_window = l->data; - gpointer child_data; GdkWindowType type; int wx, wy; - type = gdk_window_get_window_type (child_window); if (!gdk_window_is_visible (child_window) || - gdk_window_is_input_only (child_window) || - type == GDK_WINDOW_OFFSCREEN || + gdk_window_is_input_only (child_window)) + continue; + + type = gdk_window_get_window_type (child_window); + if (type == GDK_WINDOW_OFFSCREEN || type == GDK_WINDOW_FOREIGN) continue; - gdk_window_get_user_data (child_window, &child_data); - if (child_data == (gpointer)widget) - { - gdk_window_get_position (child_window, &wx, &wy); - _gtk_widget_draw_windows (child_window, cr, wx,wy); - } + gdk_window_get_position (child_window, &wx, &wy); + _gtk_widget_draw_windows (child_window, cr, wx,wy); } + g_list_free (children); } cairo_restore (cr); @@ -6471,8 +6468,7 @@ _gtk_widget_draw (GtkWidget *widget, cairo_t *cr) { GdkWindow *window, *child_window; - gpointer child_data; - GList *l; + GList *children, *l; int wx, wy; gboolean push_group; GdkWindowType type; @@ -6520,27 +6516,26 @@ _gtk_widget_draw (GtkWidget *widget, /* But, it may also have child windows in the parent which we should * draw (after having drawn on the parent) */ - for (l = g_list_last (gdk_window_peek_children (window)); - l != NULL; - l = l->prev) + children = gdk_window_get_children_with_user_data (window, widget); + for (l = children; l != NULL; l = l->next) { child_window = l->data; - type = gdk_window_get_window_type (child_window); + if (!gdk_window_is_visible (child_window) || - gdk_window_is_input_only (child_window) || - type == GDK_WINDOW_OFFSCREEN || + gdk_window_is_input_only (child_window)) + continue; + + type = gdk_window_get_window_type (child_window); + if (type == GDK_WINDOW_OFFSCREEN || type == GDK_WINDOW_FOREIGN) continue; - gdk_window_get_user_data (child_window, &child_data); - if (child_data == (gpointer)widget) - { - gdk_window_get_position (child_window, &wx, &wy); - _gtk_widget_draw_windows (child_window, cr, - wx - widget->priv->allocation.x, - wy - widget->priv->allocation.y); - } + gdk_window_get_position (child_window, &wx, &wy); + _gtk_widget_draw_windows (child_window, cr, + wx - widget->priv->allocation.x, + wy - widget->priv->allocation.y); } + g_list_free (children); } if (push_group) -- 2.30.2